<template>
  <div class="cart-div__base">
    <transition name="mask-in">
      <div
        class="cart-div__mask"
        v-show="isShowMore"
        @click="isShowMore = false"
      ></div>
    </transition>
    <div class="cart-div__content">
      <div class="cart-div__left">
        <div
          class="cart-div__icon"
          ref="icon"
          @click="toggleShowMore(!isShowMore)"
        >
          <div
            class="icon-div__wrapper"
            :class="{ 'icon-div__active': totalCount > 0 }"
          >
            <i class="icon-shopping_cart"></i>
          </div>
          <bubble
            class="icon-bubble__position"
            :showNum="totalCount"
            v-show="totalCount > 0"
          ></bubble>
        </div>
        <div class="cart-div__price" :class="hightLightPrice">
          ￥{{ totalPrice }}
        </div>
        <div class="cart-div__delivery border-left">
          另需配送费{{ deliveryPrice }}元
        </div>
      </div>
      <div
        class="cart-div__right"
        :class="hightLightButton"
        @click="handlePopUpClick"
      >
        {{
          basePrice - totalPrice > 0
            ? "￥" + (basePrice - totalPrice) + "起送"
            : "现在付款"
        }}
      </div>
      <pop-up
        @click-button="isPopUpShow = false"
        :show="isPopUpShow"
        :mask="isPopUpMaskIn"
      >
        <template>{{
          `本次订单共消费${totalPrice + deliveryPrice}元`
        }}</template>
        <template v-slot:button>去买单</template>
      </pop-up>
    </div>
    <transition name="slide-in">
      <div class="cart-div__more" v-if="isShowMore">
        <div class="more-div__title">
          <span class="more-span__intro">购物车</span>
          <button
            class="clear-button-style more-button__clear"
            @click="clearItem"
          >
            清空
          </button>
        </div>
        <div ref="morecontainer" id="more-container">
          <ul class="more-ul__list">
            <li
              class="more-li__item"
              v-for="food in cartItemList"
              :key="food.name"
            >
              <h3 class="more-li__title">{{ food.name }}</h3>
              <span class="more-span__price">{{ food.price }}</span>
              <good-button
                :count="food.foodCount"
                @addItem="moreUpdateItem(food, $event)"
                @minusItem="moreUpdateItem(food, $event)"
              ></good-button>
            </li>
          </ul>
        </div>
      </div>
    </transition>
    <drop-ball :endPosition="iconPositionInfo" ref="dropball"></drop-ball>
  </div>
</template>
<script lang="ts">
import Vue from "vue";
import BScroll from "@better-scroll/core";
import Bubble from "./../bubble-comp/bubble-comp.vue";
import DropBall from "./../drop-comp/drop-comp.vue";
import GoodButton from "./../good-button/good-button.vue";
import PopUp from "./../popup-comp/popup-comp.vue";
import {
  computed,
  Ref,
  ref,
  onMounted,
  defineComponent,
} from "@vue/composition-api";
import { storageEffect } from "./../../common/util/storage";

// 选中食物接口
interface SelectFood {
  name: string;
  price: number;
  foodCount: number;
}
// 位置信息
interface PositionInfo {
  endX: number | null;
  endY: number | null;
}
// good传入prop接口
interface ShopCartProps {
  cartItemList: SelectFood[];
  deliveryPrice: number;
  basePrice: number;
}
const iconPositionInfo: Ref<PositionInfo> = ref({ endX: null, endY: null }); // 购物车图标坐标信息
// 检查购物车的proplist类型
function checkCartPropList(prop: unknown): prop is SelectFood[] {
  return (
    prop instanceof Array &&
    prop.every(
      (data) => "name" in data && "price" in data && "foodCount" in data
    )
  );
}
// 组件部分
export default defineComponent({
  props: {
    deliveryPrice: {
      type: Number,
      required: true,
    },
    basePrice: {
      type: Number,
      required: true,
    },
    cartItemList: {
      type: Array,
      required: true,
      validator(value) {
        return checkCartPropList(value);
      },
    },
  },
  // 组件注册
  components: {
    Bubble,
    DropBall,
    PopUp,
    GoodButton,
  },
  setup(props: ShopCartProps) {
    // 图标DOM元素的模板引用
    const icon: Ref<HTMLElement | null> = ref(null);
    // 总价计算属性
    const totalPrice = computed(() => {
      let sum = 0;
      props.cartItemList.forEach((food: SelectFood) => {
        sum += food.price * food.foodCount;
      });
      return sum;
    });
    // 总数计算属性
    const totalCount = computed(() => {
      let count = 0;
      props.cartItemList.forEach((food: SelectFood) => {
        count += food.foodCount;
      });
      return count;
    });
    // 是否展示详情
    const isShowMore = ref(false);
    // 是否显示弹窗
    const isPopUpShow: Ref<boolean> = ref(false);
    // 处理弹窗点击事件
    const handlePopUpClick = function () {
      if (totalPrice.value > props.basePrice) isPopUpShow.value = true;
    };
    // 弹层组件是否需要遮罩层
    const isPopUpMaskIn = computed(() => {
      return !isShowMore.value;
    });
    // 是否高亮按钮
    const hightLightButton = computed(() => {
      // 根据是否达到起送价格判断
      return totalPrice.value >= props.basePrice ? "hightlight-button" : "";
    });
    // 是否高亮价格
    const hightLightPrice = computed(() => {
      return totalPrice.value > 0 ? "hightlight-price" : "";
    });
    const morecontainer: Ref = ref(null); // scroll容器组件
    // 勾选详情
    const toggleShowMore = (showValue: boolean) => {
      if (totalCount.value <= 0 && showValue) return; // 只有在商品总数大于1的时候才可以展开
      isShowMore.value = showValue;
      // 需要等待DOM操作完成后才能拿到正确的dom数据
      if (showValue === true) {
        Vue.nextTick(() => {
          // 初始化BetterScroll
          const bScroll = new BScroll(morecontainer.value, {
            click: true,
          });
        });
      }
    };
    // 详情栏更新物品函数
    const moreUpdateItem = function (
      this: Vue,
      food: SelectFood,
      count: number
    ) {
      this.$emit("shopcart-update", food, count);
    };
    // 清空购物车物品函数
    const clearItem = function (this: Vue) {
      this.$emit("clear-proplist");
    };
    const dropball: Ref = ref(null); // 弹球子组件的响应式引用

    // 生命周期函数
    onMounted(() => {
      // 跨组件通信-->小球动画
      storageEffect("triggerAnimate", (x: number, y: number) => {
        const pos = iconPositionInfo.value;
        // 检测是否初始化了购物车位置信息
        if (pos.endX == null && pos.endY == null && icon.value) {
          const rect = icon.value.getBoundingClientRect();
          pos.endY = rect.bottom;
          pos.endX = rect.left;
        }
        // 初始化后调用子组件方法
        if (dropball.value) dropball.value.initBall(x, y);
      });
    });
    return {
      icon,
      totalPrice,
      totalCount,
      isPopUpShow,
      isPopUpMaskIn,
      handlePopUpClick,
      hightLightButton,
      hightLightPrice,
      iconPositionInfo,
      dropball,
      isShowMore,
      toggleShowMore,
      morecontainer,
      moreUpdateItem,
      clearItem,
    };
  },
});
</script>
<style lang="stylus" scoped>
$base-height = 48px;
$base-bgc = #141d27;
$button-bgc = #2b3437;
$base-fontcolor = #80858a;
$button-fontsize = 14px;
$icon-height = 56px;
$icon-size = 24px;
$icon-active-color = white;
$icon-active-bgc = rgb(0, 160, 220);
$price-fontsize = 16px;
$delievey-height = 28px;
$more-title-bgc = #f3f5f7;
$more-color = rgb(7, 17, 27);
$more-line-color = rgba(7, 17, 27, 0.1);
$more-intro-fontsize = 14px;
$more-clear-fontsize = 12px;
$more-price-color = rgb(240, 20, 20);
$mask-bgc = rgba(7, 17, 27, 0.6);

@keyframes slide {
  0% {
    transform: translate3d(0, 0, 0);
  }

  100% {
    transform: translate3d(0, -100%, 0);
  }
}

.slide-in-enter-active {
  animation: slide 0.5s ease;
}

.slide-in-leave-active {
  animation: slide reverse 0.5s ease-in;
}

.mask-in-enter, .mask-in-leave-to {
  opacity: 0;
}

.mask-in-enter-active, .mask-in-leave-active {
  transition: opacity 0.3s ease;
}

.cart-div__base {
  height: $base-height;
  position: relative; // relative, 便于详情栏定位

  // z-index:1;// 形成层叠上下文

  // overflow: hidden; // 限制高度
  .cart-div__content {
    background-color: $base-bgc;
    display: flex;
    height: inherit;
    position: relative; // 盖住详情层
    z-index: 3; // 盖住详情层
  }
}

.cart-div__left {
  flex-grow: 1;
  text-align: left;

  .cart-div__icon {
    display: inline-block; // inline-block
    margin: 0 12px;
    box-sizing: border-box;
    position: relative; // 因为商品页上方也被relative定位了，如果不被relative定位会被盖在下方
    z-index: 3; // 盖住小球
    top: -10px;
    padding: 6px;
    width: $icon-height;
    height: $icon-height;
    background-color: $base-bgc;
    border-radius: 50%;

    .icon-div__wrapper {
      color: $base-fontcolor;
      background-color: $button-bgc;
      width: 100%;
      height: 100%;
      border-radius: inherit;
      text-align: center;
      font-size: $icon-size;
      line-height: 44px;
      transition: background-color linear 0.3s, color linear 0.3s;
    }

    .icon-div__active {
      color: $icon-active-color;
      background-color: $icon-active-bgc;
    }

    .icon-bubble__position {
      position: absolute;
      right: 0;
      top: 0;
    }
  }

  .cart-div__price {
    display: inline-block; // inline-block
    font-size: $price-fontsize;
    height: $base-height;
    vertical-align: top;
    line-height: $base-height;
    font-weight: 700;
    color: $base-fontcolor;
    padding-right: 12px;
  }

  .hightlight-price {
    color: $icon-active-color;
  }

  .cart-div__delivery {
    display: inline-block;
    margin: 10px 0;
    vertical-align: top;
    height: $delievey-height;
    line-height: $delievey-height;
    color: $base-fontcolor;
    font-size: 14px;
    padding-left: 12px;
    position: relative;

    // 如果屏幕太小直接删除这个部分
    @media screen and (max-width: 350px) {
      & {
        display: none;
      }
    }

    // border-left: 1px solid rgba(255, 255, 255, 0.1);
    &.border-left::after {
      content: '';
      left: 0;
      top: 0;
      bottom: 0;
      width: 1px;
      position: absolute;
      background-color: rgba(255, 255, 255, 0.1);
    }

    @media (-webkit-device-pixel-ratio: 2), (-webkit-max-device-pixel-ratio: 2), (-webkit-min-pixel-ratio: 2) {
      &.border-left::after {
        transform: scaleX(0.5);
      }
    }
  }
}

.cart-div__right {
  width: 105px;
  line-height: $base-height;
  background-color: $button-bgc;
  text-align: center;
  font-weight: 700;
  font-size: $button-fontsize;
  color: $base-fontcolor;
  transition: all 0.3s linear; // 动画效果
}

// 按钮高亮样式
.hightlight-button {
  color: $icon-active-color;
  background-color: $icon-active-bgc;
}

// 去掉button默认样式
.clear-button-style {
  border: none;
  background-color: inherit; // 
  -webkit-appearance: none;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);

  &:focus {
    border: 0 none;
    outline: none;
  }
}

// 购物车详情样式
.cart-div__more {
  position: absolute; // 绝对定位
  top: 0;
  left: 0;
  right: 0; // hack，覆盖全屏幕宽
  max-height: 305px;
  background-color: white;
  transform: translate3d(0, -100%, 0); // 测试
  z-index: 2; // 盖住蒙层

  // overflow: hidden; // 不允许超出下方
  .more-div__title {
    background-color: $more-title-bgc;
    line-height: 40px;
    padding: 0 18px;
    display: flex;
    justify-content: space-between;
    border-bottom: 1px solid $more-line-color;
    border-top: 1px solid $more-line-color;

    .more-span__intro {
      font-size: $more-intro-fontsize;
      color: $more-color;
    }

    .more-button__clear {
      font-size: $more-clear-fontsize;
      color: $icon-active-bgc;
    }
  }

  #more-container {
    max-height: 265px; // 容器限制高度
    overflow-y: hidden;
  }

  .more-ul__list {
    margin: 0 18px;

    // box-sizing: border-box;
    // padding-bottom: 48px;
    .more-li__item {
      display: flex; // flex
      align-items: center;
      padding: 12px 0;
      box-sizing: border-box;
      height: 48px;
      position: relative; // relative-->for border-bottom

      &::after {
        content: '';
        height: 1px;
        bottom: 0;
        left: 0;
        right: 0;
        position: absolute;
        background-color: $more-line-color;
      }

      @media (-webkit-device-pixel-ratio: 2), (-webkit-max-device-pixel-ratio: 2), (-webkit-min-pixel-ratio: 2) {
        &::after {
          transform: scaleY(0.5);
        }
      }

      // 最后一个元素没有下划线
      &:last-child::after {
        display: none;
      }

      .more-li__title {
        text-align: left;
        font-size: $more-intro-fontsize;
        font-weight: 700;
        color: $more-color;
        flex-grow: 1;
      }

      .more-span__price {
        padding-right: 12px;
        font-size: $price-fontsize;
        color: $more-price-color;
        font-weight: 700;
      }
    }
  }
}

.cart-div__mask {
  position: fixed;
  top: 0;
  bottom: 0;
  width: 100%;
  z-index: 2; // 盖住商品详情页
  background-color: $mask-bgc;
  backdrop-filter: blur(5px); // 兼容性可能不好
}
</style>
